package com.sf.fy.uav.applet.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sf.fy.uav.applet.config.DelayQueue;
import com.sf.fy.uav.common.enums.ServicePrefixEnum;
import com.sf.fy.uav.common.enums.SettingStatusEnum;
import com.sf.fy.uav.common.request.common.IdRequest;
import com.sf.fy.uav.common.request.operate.*;
import com.sf.fy.uav.common.request.order.DealRequest;
import com.sf.fy.uav.common.response.operational.SysCouponActivityResponse;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.RedisPrefixKey;
import com.sf.fy.uav.controller.CouponActivityDetailController;
import com.sf.fy.uav.entity.*;
import com.sf.fy.uav.mapper.CouponActivityDetailMapper;
import com.sf.fy.uav.mapper.CouponActivityMapper;
import com.sf.fy.uav.applet.service.ISysCouponActivityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 优惠券活动表 服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2024-08-26
 */
@Service
public class SysCouponActivityServiceImpl extends ServiceImpl<CouponActivityMapper, CouponActivity> implements ISysCouponActivityService {

    @Autowired
    private CouponActivityMapper couponActivityMapper;

    @Autowired
    private CouponActivityDetailMapper couponActivityDetailMapper;

    @Autowired
    private DelayQueue delayQueue;

    @Autowired
    private CouponActivityDetailController couponActivityDetailController;


    private static final Integer DEL = 0;

    @Override
    public void addCouponActivity(CouponActivityAddRequest couponActivityAddRequest) {
        Date date = new Date();
        CouponActivity couponActivity = BeanUtil.copyProperties(couponActivityAddRequest, CouponActivity.class);
        couponActivity.setUpdateTime(date);
        couponActivity.setCreateTime(date);
        couponActivity.setDeleted(false);
        Date startTime = couponActivityAddRequest.getStartActivityTime();
        Date endTime = couponActivityAddRequest.getEndActivityTime();
        if (date.getTime() > startTime.getTime()) {
            throw new RuntimeException("开始时间不能小于当前时间!");
        }
        if (startTime.getTime() >= endTime.getTime()) {
            throw new RuntimeException("开始时间不能大于等于结束时间!");
        }
        dateSubtract(couponActivityAddRequest.getStartActivityTime(), couponActivityAddRequest.getEndActivityTime());
        if (startTime.getTime() > date.getTime()) {
            //还没开始
            couponActivity.setStatus(SettingStatusEnum.NOT_STARTED.getStatus());
        } else {
            if (date.getTime() < endTime.getTime()) {
                couponActivity.setStatus(SettingStatusEnum.ON_DISPLAY.getStatus());
            } else {
                couponActivity.setStatus(SettingStatusEnum.ENDED.getStatus());
            }
        }
        //做新增时这段活动时间范围内有无其他活动的验重判断
        QueryWrapper<CouponActivity> activityQueryWrapper = new QueryWrapper<>();
        activityQueryWrapper.ne("status", SettingStatusEnum.OFF.getStatus());
        activityQueryWrapper.eq("deleted", DEL);
        List<CouponActivity> activitieList = couponActivityMapper.selectList(activityQueryWrapper);
        for (CouponActivity activityEntry : activitieList) {
            long startActivityTimeLong = activityEntry.getStartActivityTime().getTime();
            long endActivityTimeLong = activityEntry.getEndActivityTime().getTime();
            if (startTime.getTime() < endActivityTimeLong && endTime.getTime() > startActivityTimeLong) {
                throw new RuntimeException("当前时间段内存在其他活动,请重新设置!");
            }
        }
        couponActivityMapper.insert(couponActivity);
        if (startTime.getTime() > date.getTime()) {
            //还没开始
//            //设置到期自动上架
            delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_UP_COUNT_DOWN + couponActivity.getId(), startTime.getTime() - date.getTime());
        } else {
            if (date.getTime() < endTime.getTime()) {
//                //设置到期自动下架
                delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_DOWN_COUNT_DOWN + couponActivity.getId(), endTime.getTime() - date.getTime());
            }
        }
        List<CouponActivityDetailAddRequest> couponActivityDetailAddRequests = couponActivityAddRequest.getCouponActivityDetailAddRequests();
        for (CouponActivityDetailAddRequest couponActivityDetailAddRequest : couponActivityDetailAddRequests) {
            CouponActivityDetail couponActivityDetail = new CouponActivityDetail();
            couponActivityDetail.setCouponActivityId(couponActivity.getId());
            couponActivityDetail.setCouponId(couponActivityDetailAddRequest.getCouponId());
            couponActivityDetail.setCnt(couponActivityDetailAddRequest.getCnt());
            couponActivityDetail.setCouponName(couponActivityDetailAddRequest.getCouponName());
            couponActivityDetail.setUpdateTime(date);
            couponActivityDetail.setCreateTime(date);
            couponActivityDetail.setCouponName(couponActivityDetail.getCouponName());
            couponActivityDetailMapper.insert(couponActivityDetail);
        }
    }


    private void dateSubtract(Date startDate, Date endDate) {
        DateFormat fat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate date1 = LocalDate.parse(fat.format(startDate), formatter);
        LocalDate date2 = LocalDate.parse(fat.format(endDate), formatter);
        Period period = Period.between(date1, date2);
        int years = period.getYears();
        if (years >= 1) {
            throw new RuntimeException("时间跨度最大一年!");
        }
    }

    @Override
    public void editCouponActivity(CouponActivityEditRequest couponActivityEditRequest) {
        String id = couponActivityEditRequest.getId();
        if (ObjectUtils.isEmpty(id)) {
            throw new RuntimeException("id不能为空");
        }
        CouponActivity couponActivity = couponActivityMapper.selectById(id);
        Date date = new Date();
        if (Objects.equals(SettingStatusEnum.NOT_STARTED.getStatus(), couponActivity.getStatus())) {

            if (couponActivityEditRequest.getStartActivityTime() == null) {
                throw new RuntimeException("开始时间不能为空!");
            }
            if (ObjectUtils.isEmpty(couponActivity)) {
                throw new RuntimeException("记录不存在");
            }
            if (ObjectUtils.isEmpty(couponActivity)) {
                throw new RuntimeException("记录不存在");
            }
            if (date.getTime() > couponActivityEditRequest.getStartActivityTime().getTime()) {
                throw new RuntimeException("开始时间不能小于当前时间!");
            }
            if (couponActivityEditRequest.getStartActivityTime().getTime() >= couponActivityEditRequest.getEndActivityTime().getTime()) {
                throw new RuntimeException("开始时间不能大于等于结束时间");
            }
            dateSubtract(couponActivityEditRequest.getStartActivityTime(), couponActivityEditRequest.getEndActivityTime());
        }

        if (Objects.equals(SettingStatusEnum.ON_DISPLAY.getStatus(), couponActivity.getStatus())) {
            if (couponActivity.getStartActivityTime().getTime() >= couponActivityEditRequest.getEndActivityTime().getTime()) {
                throw new RuntimeException("结束时间不能小于开始时间");
            }
            dateSubtract(couponActivity.getStartActivityTime(), couponActivityEditRequest.getEndActivityTime());
        }
        List<CouponActivity> activitieEndAndOffList = couponActivityMapper.selectList(new QueryWrapper<CouponActivity>().and(wrapper -> wrapper.eq("status", SettingStatusEnum.ENDED.getStatus())).or(wrapper -> wrapper.eq("status", SettingStatusEnum.OFF.getStatus())).and(wrapper -> wrapper.eq("deleted", DEL)));
        List<String> endAndOffIds = activitieEndAndOffList.stream().map(CouponActivity::getId).toList();
        if (endAndOffIds.contains(id)) {
            throw new RuntimeException("已结束或已下架的活动禁止修改!");
        }

        String activityName = couponActivityEditRequest.getActivityName();
        Date endActivityTime = couponActivityEditRequest.getEndActivityTime();
        Date startActivityTime = couponActivityEditRequest.getStartActivityTime();
        String processedBy = couponActivityEditRequest.getProcessedBy();

        if (!Objects.equals(SettingStatusEnum.ON_DISPLAY.getStatus(), couponActivity.getStatus())) {
            if (!ObjectUtils.isEmpty(activityName)) {
                couponActivity.setActivityName(activityName);
            }
            if (!ObjectUtils.isEmpty(startActivityTime)) {
                couponActivity.setStartActivityTime(startActivityTime);
            }
        }


        if (!ObjectUtils.isEmpty(endActivityTime)) {
            couponActivity.setEndActivityTime(endActivityTime);
        }
        if (!ObjectUtils.isEmpty(processedBy)) {
            couponActivity.setProcessedBy(processedBy);
        }
        startActivityTime = couponActivity.getStartActivityTime();
        endActivityTime = couponActivity.getEndActivityTime();
        if (startActivityTime.getTime() > date.getTime()) {
            //还没开始
            couponActivity.setStatus(SettingStatusEnum.NOT_STARTED.getStatus());
//            //设置自动上架
            delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_UP_COUNT_DOWN + couponActivity.getId(), startActivityTime.getTime() - date.getTime());
        } else {
            if (date.getTime() < endActivityTime.getTime()) {
                couponActivity.setStatus(SettingStatusEnum.ON_DISPLAY.getStatus());
//                //设置自动下架
                delayQueue.pushQueue(ServicePrefixEnum.EXPRESS_SYSTEM + RedisPrefixKey.COUPON_ACTIVITY_DOWN_COUNT_DOWN + couponActivity.getId(), endActivityTime.getTime() - date.getTime());
            } else {
                couponActivity.setStatus(SettingStatusEnum.ENDED.getStatus());
            }
        }
        //做编辑时这段活动时间范围内有无其他活动的验重判断
        List<CouponActivity> activitieList = couponActivityMapper.selectList(new QueryWrapper<CouponActivity>().and(wrapper -> wrapper.eq("deleted", DEL)).and(wrapper -> wrapper.eq("status", SettingStatusEnum.NOT_STARTED.getStatus())).or(wrapper -> wrapper.eq("status", SettingStatusEnum.ON_DISPLAY.getStatus())));
        for (CouponActivity activityEntry : activitieList) {
            if (id.equals(activityEntry.getId())) {
                continue;
            }
            if (activityEntry.getDeleted()) {
                continue;
            }

            long startActivityTimeLong = activityEntry.getStartActivityTime().getTime();
            long endActivityTimeLong = activityEntry.getEndActivityTime().getTime();
            if (startActivityTime.getTime() < endActivityTimeLong && endActivityTime.getTime() > startActivityTimeLong) {
                throw new RuntimeException("当前时间段内存在其他活动,请重新设置!");
            }
        }
        couponActivity.setUpdateTime(date);
        couponActivityMapper.updateById(couponActivity);
        List<CouponActivityDetailEditRequest> couponActivityDetailEditRequests = couponActivityEditRequest.getCouponActivityDetailEditRequests();
        if (!CollectionUtils.isEmpty(couponActivityDetailEditRequests)) {
            List<String> ids = couponActivityDetailEditRequests.stream().map(CouponActivityDetailEditRequest::getId).toList();
            List<CouponActivityDetail> couponActivityDetails = couponActivityDetailController.getDetailsByCouponActivityIds(List.of(id));
            couponActivityDetails.forEach(couponActivityDetail -> {
                if (ids.contains(couponActivityDetail.getId())) {
                    //编辑
                    for (CouponActivityDetailEditRequest couponActivityDetailEditRequest1 : couponActivityDetailEditRequests) {
                        if (couponActivityDetailEditRequest1.getId().equals(couponActivityDetail.getId())) {
                            couponActivityDetail.setCnt(couponActivityDetailEditRequest1.getCnt());
                            couponActivityDetail.setCouponId(couponActivityDetailEditRequest1.getCouponId());
                            couponActivityDetail.setCouponName(couponActivityDetailEditRequest1.getCouponName());
                            couponActivityDetail.setUpdateTime(date);
                            couponActivityDetailMapper.updateById(couponActivityDetail);
                        }
                    }
                } else {
                    //删除多余的
                    couponActivityDetailMapper.deleteById(couponActivityDetail.getId());
                }
            });

            couponActivityDetailEditRequests.forEach(couponActivityDetailEditRequest -> {
                if (!couponActivityDetails.stream().map(CouponActivityDetail::getId).toList().contains(couponActivityDetailEditRequest.getId())) {
                    //新增
                    CouponActivityDetail couponActivityDetail = new CouponActivityDetail();
                    couponActivityDetail.setCouponActivityId(couponActivity.getId());
                    couponActivityDetail.setCouponId(couponActivityDetailEditRequest.getCouponId());
                    couponActivityDetail.setCnt(couponActivityDetailEditRequest.getCnt());
                    couponActivityDetail.setCouponName(couponActivityDetailEditRequest.getCouponName());
                    couponActivityDetail.setUpdateTime(date);
                    couponActivityDetail.setCreateTime(date);
                    couponActivityDetail.setCouponName(couponActivityDetail.getCouponName());
                    couponActivityDetailMapper.insert(couponActivityDetail);
                }
            });


        }

    }

    private Boolean checkIsRight(Date endActivityTime, Date startActivityTime, Integer rewardType) {
        QueryWrapper<CouponActivity> activityQueryWrapper = new QueryWrapper<>();
//        activityQueryWrapper.eq();
//        if () {
//
//        }
        return null;
    }

    private QueryWrapper getQueryWrapper(String name, Integer status) {
        QueryWrapper<CouponActivity> activityQueryWrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(name)) {
            activityQueryWrapper.like("activity_name", name);
        }
        if (!ObjectUtils.isEmpty(status)) {
            activityQueryWrapper.eq("status", status);
        }
        activityQueryWrapper.eq("deleted", false);
        return activityQueryWrapper;
    }

    @Override
    public Long getTotal(String name, Integer status) {
        QueryWrapper<CouponActivity> activityQueryWrapper = this.getQueryWrapper(name, status);
        return couponActivityMapper.selectCount(activityQueryWrapper);
    }

    @Override
    public List<SysCouponActivityResponse> getCouponActivity(SysCouponActivityRequest sysCouponActivityRequest) {
        String name = sysCouponActivityRequest.getCouponActivityName();
        Integer status = sysCouponActivityRequest.getStatus();
        QueryWrapper<CouponActivity> activityQueryWrapper = this.getQueryWrapper(name, status);
        activityQueryWrapper.orderByDesc("update_time");
        Page<CouponActivity> couponActivityPage = new Page<>(sysCouponActivityRequest.getPage(), sysCouponActivityRequest.getSize());
        IPage<CouponActivity> couponActivityIPage = couponActivityMapper.selectPage(couponActivityPage, activityQueryWrapper);
        List<CouponActivity> couponActivities = couponActivityIPage.getRecords();
        List<SysCouponActivityResponse> sysCouponActivityResponses = new ArrayList<>();

        if (!CollectionUtils.isEmpty(couponActivities)) {
            List<String> couponActivitiesId = couponActivities.stream().map(CouponActivity::getId).toList();
            List<CouponActivityDetail> couponActivityDetails = couponActivityDetailController.getDetailsByCouponActivityIds(couponActivitiesId);
            couponActivities.forEach(couponActivity -> {
                Integer cnt = couponActivityDetails.stream().filter(couponActivityDetail -> couponActivityDetail.getCouponActivityId().equals(couponActivity.getId())).map(CouponActivityDetail::getCnt).reduce(Integer::sum).get();
                SysCouponActivityResponse sysCouponActivityResponse = BeanUtil.copyProperties(couponActivity, SysCouponActivityResponse.class);
                sysCouponActivityResponse.setCnt(cnt);
                sysCouponActivityResponses.add(sysCouponActivityResponse);
            });
        }
        return sysCouponActivityResponses;
    }

    @Override
    public void off(DealRequest dealRequest) {
        String id = dealRequest.getId();
        if (ObjectUtils.isEmpty(id)) {
            throw new RuntimeException("id不能为空");
        }
        CouponActivity couponActivity = couponActivityMapper.selectById(id);
        if (ObjectUtils.isEmpty(couponActivity)) {
            throw new RuntimeException("记录不存在");
        }
        couponActivity.setStatus(SettingStatusEnum.OFF.getStatus());
        couponActivity.setUpdateTime(new Date());
        couponActivity.setOffReason("手动下架");
        couponActivityMapper.updateById(couponActivity);
    }

    @Override
    public void delete(DealRequest dealRequest) {
        String id = dealRequest.getId();
        if (ObjectUtils.isEmpty(id)) {
            throw new RuntimeException("id不能为空");
        }
        CouponActivity couponActivity = couponActivityMapper.selectById(id);
        if (ObjectUtils.isEmpty(couponActivity)) {
            throw new RuntimeException("记录不存在");
        }
        couponActivity.setDeleted(true);
        couponActivity.setUpdateTime(new Date());
        couponActivityMapper.updateById(couponActivity);
    }


    @Override
    public Boolean checkEffectiveness(String activityId) {
        Date date = new Date();
        QueryWrapper<CouponActivity> activityQueryWrapper = new QueryWrapper<>();
        activityQueryWrapper.eq("id", activityId);
        activityQueryWrapper.eq("deleted", false);
        activityQueryWrapper.le("start_activity_time", date);
        activityQueryWrapper.ge("end_activity_time", date);
        activityQueryWrapper.ne("status", SettingStatusEnum.OFF.getStatus());
        CouponActivity couponActivity = couponActivityMapper.selectOne(activityQueryWrapper);
        return !ObjectUtils.isEmpty(couponActivity);
    }

    @Override
    public Integer start(IdRequest idRequest) {
        CouponActivity couponActivity = couponActivityMapper.selectById(idRequest.getId());
        if (!ObjectUtils.isEmpty(couponActivity)) {
            if (couponActivity.getDeleted() || couponActivity.getStatus().equals(SettingStatusEnum.OFF.getStatus())) {
                return null;
            }
            if (!ObjectUtils.isEmpty(couponActivity)) {
                Date startTime = couponActivity.getStartActivityTime();
                Date endTime = couponActivity.getEndActivityTime();
                Date date = new Date();
                if (startTime.getTime() > date.getTime()) {
                    //还没开始
                    couponActivity.setStatus(SettingStatusEnum.NOT_STARTED.getStatus());
                } else {
                    if (date.getTime() < endTime.getTime()) {
                        couponActivity.setStatus(SettingStatusEnum.ON_DISPLAY.getStatus());
                    } else {
                        couponActivity.setStatus(SettingStatusEnum.ENDED.getStatus());
                    }
                }
                couponActivityMapper.updateById(couponActivity);
                return couponActivity.getStatus();
            }
        }
        return null;
    }

    @Override
    public Integer end(IdRequest idRequest) {
        CouponActivity couponActivity = couponActivityMapper.selectById(idRequest.getId());
        if (ObjectUtils.isEmpty(couponActivity)) {
            return null;
        }
        if (couponActivity.getDeleted() || couponActivity.getStatus().equals(SettingStatusEnum.OFF.getStatus())) {
            return null;
        }
        if (!ObjectUtils.isEmpty(couponActivity)) {
            Date startTime = couponActivity.getStartActivityTime();
            Date endTime = couponActivity.getEndActivityTime();
            Date date = new Date();
            if (startTime.getTime() > date.getTime()) {
                //还没开始
                couponActivity.setStatus(SettingStatusEnum.NOT_STARTED.getStatus());
            } else {
                if (date.getTime() < endTime.getTime()) {
                    couponActivity.setStatus(SettingStatusEnum.ON_DISPLAY.getStatus());
                } else {
                    couponActivity.setStatus(SettingStatusEnum.ENDED.getStatus());
                }
            }
            couponActivityMapper.updateById(couponActivity);
            return couponActivity.getStatus();
        }
        return null;
    }

}
